home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
3D GFX
/
3D GFX.iso
/
amiutils
/
i_l
/
irit5
/
irit
/
objects1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-30
|
34KB
|
855 lines
/*****************************************************************************
* "Irit" - the 3d (not only polygonal) solid modeller. *
* *
* Written by: Gershon Elber Ver 0.2, Mar. 1990 *
******************************************************************************
* Module to handle the objects list - fetch, insert, delete etc... *
*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "program.h"
#include "allocate.h"
#include "attribut.h"
#include "primitiv.h"
#include "geomat3d.h"
#include "objects.h"
#include "freeform.h"
#include "windows.h"
#define IS_FLOAT_PRINTF_CMD(c) ((c) == 'e' || (c) == 'f' || (c) == 'g' || \
(c) == 'E' || (c) == 'F')
#define IS_PRINTF_CMD(c) (IS_FLOAT_PRINTF_CMD(c) || \
(c) == 'd' || (c) == 'i' || (c) == 'u' || \
(c) == 'o' || (c) == 'x' || (c) == 'X' || \
(c) == 's' || (c) == 'p' || (c) == 'v' || \
(c) == 'P' || (c) == 'D')
static IPPolygonStruct *GenAxesObjectPolylines(void);
/*****************************************************************************
* DESCRIPTION: M
* Routine to set up all the predefined objects - objects that the system M
* must have all the time, like global transformation matrices. M
* *
* PARAMETERS: M
* None *
* *
* RETURN VALUE: M
* void M
* M
* KEYWORDS: M
* SetUpPredefObjects M
*****************************************************************************/
void SetUpPredefObjects(void)
{
RealType R;
MatrixType Mat1, Mat2;
IPObjectStruct *PObj;
/* 90 - 35.2644 = 54.7356 */
MatGenMatRotX1(DEG2RAD(-54.7356), Mat1); /* Generate default view trans. */
MatGenMatRotZ1(M_PI+M_PI/4, Mat2); /* which is isometric view. */
MatMultTwo4by4(Mat2, Mat2, Mat1);
PObj = GenMatObject("VIEW_MAT", Mat2, NULL);
InsertObject(PObj);
MatGenUnitMat(Mat1); /* Generate default perspective trans. */
Mat1[2][2] = 0.1;
Mat1[2][3] = -0.35;
Mat1[3][2] = 0.35;
PObj = GenMatObject("PRSP_MAT", Mat1, NULL);
InsertObject(PObj);
R = DEFAULT_RESOLUTION;
PObj = GenNumObject("RESOLUTION", &R, NULL);
InsertObject(PObj);
R = DEFAULT_DRAW_CTLPT;
PObj = GenNumObject("DRAWCTLPT", &R, NULL);
InsertObject(PObj);
R = 0;
PObj = GenNumObject("FLAT4PLY", &R, NULL);
InsertObject(PObj);
R = 0;
PObj = GenNumObject("POLY_APPROX_OPT", &R, NULL);
InsertObject(PObj);
R = 0;
PObj = GenNumObject("POLY_APPROX_UV", &R, NULL);
InsertObject(PObj);
R = 0.3;
PObj = GenNumObject("POLY_APPROX_TOL", &R, NULL);
InsertObject(PObj);
R = MACHINE_UNIX;
#if defined(__MSDOS__) || defined(DJGCC)
R = MACHINE_MSDOS;
#endif
#if defined(sgi)
R = MACHINE_SGI;
#endif
#if defined(hpbsd) || defined(hpux) || defined(__hpux)
R = MACHINE_HP;
#endif
#if defined(sun)
R = MACHINE_SUN;
#endif
#if defined(apollo)
R = MACHINE_APOLLO;
#endif
#if defined(OS2GCC)
R = MACHINE_IBMOS2;
#endif
#if defined(WIN32NT)
R = MACHINE_IBMNT;
#endif
#if defined(AMIGA)
R = MACHINE_AMIGA;
#endif
PObj = GenNumObject("MACHINE", &R, NULL);
InsertObject(PObj);
PObj = GenPolyObject("AXES", GenAxesObjectPolylines(), NULL);
IP_SET_POLYLINE_OBJ(PObj); /* Mark it as polyline object. */
InsertObject(PObj);
}
/*****************************************************************************
* DESCRIPTION: M
* Routine to set an attribute of an object. M
* *
* PARAMETERS: M
* PObj: To set an attribute for. M
* Name: Name of attribute. M
* Data: new value of attribute M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* SetObjectAttrib M
*****************************************************************************/
void SetObjectAttrib(IPObjectStruct *PObj, char *Name, IPObjectStruct *Data)
{
if (IP_IS_STR_OBJ(Data))
AttrSetObjectStrAttrib(PObj, Name, Data -> U.Str);
else if (IP_IS_NUM_OBJ(Data)) {
RealType
r = Data -> U.R;
if (r == (int) r)
AttrSetObjectIntAttrib(PObj, Name, (int) r);
else
AttrSetObjectRealAttrib(PObj, Name, r);
}
else
AttrSetObjectObjAttrib(PObj, Name, Data, TRUE);
}
/*****************************************************************************
* DESCRIPTION: M
* Routine to remove an attribute from an object. M
* *
* PARAMETERS: M
* PObj: To remover an attribute from. M
* Name: Name of attribute. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* RemoveObjectAttrib M
*****************************************************************************/
void RemoveObjectAttrib(IPObjectStruct *PObj, char *Name)
{
AttrFreeOneAttribute(&PObj -> Attrs, Name);
}
/*****************************************************************************
* DESCRIPTION: *
* Generate an axis coordinate system with length of 1 on each axis. *
* *
* PARAMETERS: *
* None *
* *
* RETURN VALUE: *
* IPPolygonStruct *: A polyline representing the XYZ coordinate system. *
*****************************************************************************/
static IPPolygonStruct *GenAxesObjectPolylines(void)
{
IPPolygonStruct *Pl, *PlHead;
IPVertexStruct *V;
/* X axis. */
Pl = PlHead = IPAllocPolygon(0, 0, NULL, NULL);
Pl -> PVertex = V = IPAllocVertex(0, 0, NULL, NULL);
V -> Coord[0] = 0.0; V -> Coord[1] = 0.0; V -> Coord[2] = 0.0;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 1.0; V -> Coord[1] = 0.0; V -> Coord[2] = 0.0;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 1.0; V -> Coord[1] = 0.1; V -> Coord[2] = 0.1;
Pl -> Pnext = IPAllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;
Pl -> PVertex = V = IPAllocVertex(0, 0, NULL, NULL);
V -> Coord[0] = 1.0; V -> Coord[1] = 0.1; V -> Coord[2] = 0.0;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 1.0; V -> Coord[1] = 0.0; V -> Coord[2] = 0.1;
/* Y axis.*/
Pl -> Pnext = IPAllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;
Pl -> PVertex = V = IPAllocVertex(0, 0, NULL, NULL);
V -> Coord[0] = 0.0; V -> Coord[1] = 0.0; V -> Coord[2] = 0.0;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 0.0; V -> Coord[1] = 1.0; V -> Coord[2] = 0.0;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 0.0; V -> Coord[1] = 1.0; V -> Coord[2] = 0.06;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 0.04; V -> Coord[1] = 1.0; V -> Coord[2] = 0.1;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 0.0; V -> Coord[1] = 1.0; V -> Coord[2] = 0.06;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] =(-0.04); V -> Coord[1] = 1.0; V -> Coord[2] = 0.1;
/* Z axis.*/
Pl -> Pnext = IPAllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;
Pl -> PVertex = V = IPAllocVertex(0, 0, NULL, NULL);
V -> Coord[0] = 0.0; V -> Coord[1] = 0.0; V -> Coord[2] = 0.0;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 0.0; V -> Coord[1] = 0.0; V -> Coord[2] = 1.0;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 0.1; V -> Coord[1] = 0.0; V -> Coord[2] = 1.0;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 0.0; V -> Coord[1] = 0.1; V -> Coord[2] = 1.0;
V -> Pnext = IPAllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
V -> Coord[0] = 0.1; V -> Coord[1] = 0.1; V -> Coord[2] = 1.0;
return PlHead;
}
/*****************************************************************************
* DESCRIPTION: M
* Returns the type of an object. M
* If object is not found, an undefined type is returned. M
* *
* PARAMETERS: M
* Name: Of object to query type. M
* *
* RETURN VALUE: M
* double: Type of object, coerced to double M
* *
* KEYWORDS: M
* ThisObjectIs M
*****************************************************************************/
double ThisObjectIs(char *Name)
{
int i;
IPObjectStruct *PObj;
for (i = 0; i < strlen(Name); i++)
if (islower(Name[i]))
Name[i] = toupper(Name[i]);
PObj = GetObject(Name);
return (double) (PObj == NULL ? IP_OBJ_UNDEF : (PObj -> ObjType));
}
/*****************************************************************************
* DESCRIPTION: M
* General printf routine, IRIT's style, to stdout. M
* *
* PARAMETERS: M
* CtlStr: Control string of this printf. M
* PObjLst: List of object to print. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* IritObjectPrintfStdout M
*****************************************************************************/
void IritObjectPrintfStdout(char *CtlStr, IPObjectStruct *PObjLst)
{
IritObjectPrintf(stdout, CtlStr, PObjLst);
}
/*****************************************************************************
* DESCRIPTION: M
* General printf routine, IRIT's style. M
* *
* PARAMETERS: M
* File: File descriptor of where this all goes. M
* CtlStr: Control string of this printf. M
* PObjLst: List of object to print. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* IritObjectPrintf M
*****************************************************************************/
void IritObjectPrintf(FILE *File, char *CtlStr, IPObjectStruct *PObjLst)
{
char Buffer[LINE_LEN], Line[LINE_LEN_LONG];
int i, j, k,
CrntItem = 0,
NumOfItems = ListObjectLength(PObjLst);
IPObjectStruct *CrntObj;
Line[0] = 0;
for (i = 0; i < strlen(CtlStr); i++) {
if (CtlStr[i] == '%') {
for (j = 0; j < 10 && !IS_PRINTF_CMD(CtlStr[i]); j++, i++)
Buffer[j] = CtlStr[i];
Buffer[j++] = CtlStr[i];
Buffer[j--] = 0;
if (CrntItem >= NumOfItems) {
WndwInputWindowPutStr("PRINTF: Not enough objects for printf.");
return;
}
CrntObj = ListObjectGet(PObjLst, CrntItem++);
switch (Buffer[j]) {
case 'c':
if (IP_IS_NUM_OBJ(CrntObj)) {
sprintf(&Line[strlen(Line)], Buffer,
(int) CrntObj -> U.R);
}
else {
WndwInputWindowPutStr("PRINTF: Number expected.");
return;
}
break;
case 'd':
case 'i':
case 'u':
case 'o':
case 'x':
case 'X':
if (IP_IS_NUM_OBJ(CrntObj)) {
sprintf(&Line[strlen(Line)], Buffer,
(int) CrntObj -> U.R);
}
else {
WndwInputWindowPutStr("PRINTF: Number expected.");
return;
}
break;
case 'e':
case 'f':
case 'g':
case 'E':
case 'G':
if (IP_IS_NUM_OBJ(CrntObj)) {
sprintf(&Line[strlen(Line)], Buffer,
CrntObj -> U.R);
}
else {
WndwInputWindowPutStr("PRINTF: Number expected.");
return;
}
break;
case 's':
if (IP_IS_STR_OBJ(CrntObj)) {
sprintf(&Line[strlen(Line)], Buffer,
CrntObj -> U.Str);
}
else {
WndwInputWindowPutStr("PRINTF: String expected.");
return;
}
break;
case 'p':
case 'v':
if (!IP_IS_VEC_OBJ(CrntObj) &&
!IP_IS_POINT_OBJ(CrntObj)) {
WndwInputWindowPutStr(
"PRINTF: Vector or Point expected.");
return;
}
Buffer[j] = CtlStr[++i];
if (!IS_FLOAT_PRINTF_CMD(Buffer[j])) {
WndwInputWindowPutStr(
"PRINTF: Floaing point number command expected.");
return;
}
for (k = 0; k < 3; k++) {
sprintf(&Line[strlen(Line)],
Buffer, CrntObj -> U.Vec[k]);
if (k < 2)
strcat(Line, ", ");
}
break;
case 'P':
if (!IP_IS_PLANE_OBJ(CrntObj)) {
WndwInputWindowPutStr("PRINTF: Plane expected.");
return;
}
Buffer[j] = CtlStr[++i];
if (!IS_FLOAT_PRINTF_CMD(Buffer[j])) {
WndwInputWindowPutStr(
"PRINTF: Floaing point number command expected.");
return;
}
for (k = 0; k < 4; k++) {
sprintf(&Line[strlen(Line)],
Buffer, CrntObj -> U.Plane[k]);
if (k < 3)
strcat(Line, ", ");
}
break;
case 'D':
Buffer[j] = CtlStr[++i];
IritPrsrSetFloatFormat(Buffer);
if (strlen(Line) > 0) {
WndwInputWindowPutStr(Line);
Line[0] = 0;
}
PrintObject(CrntObj);
IritPrsrSetFloatFormat(GlblFloatFormat);
break;
default:
WndwInputWindowPutStr(
"PRINTF: Unknown % control to print command.");
return;
}
}
else if (CtlStr[i] == '\\') {
k = strlen(Line);
switch (CtlStr[++i]) {
case 't':
Line[k] = '\t';
break;
case 'n':
Line[k] = '\n';
break;
case '%':
Line[k] = '%';
break;
}
Line[++k] = 0;
}
else {
k = strlen(Line);
Line[k++] = CtlStr[i];
Line[k] = 0;
}
}
if (strlen(Line) > 0)
WndwInputWindowPutStr(Line);
}
/*****************************************************************************
* DESCRIPTION: M
* Gets the size of an object. M
* *
* PARAMETERS: M
* Obj: Object to query size of. M
* *
* RETURN VALUE: M
* double: Size of object Obj, coerced to double. M
* *
* KEYWORDS: M
* GetObjectSize M
*****************************************************************************/
double GetObjectSize(IPObjectStruct *Obj)
{
if (IP_IS_POLY_OBJ(Obj)) {
if (Obj -> U.Pl -> Pnext == NULL)
return (double) IritPrsrVrtxListLen(Obj -> U.Pl -> PVertex);
else
return (double) IritPrsrPolyListLen(Obj -> U.Pl);
}
else if (IP_IS_CRV_OBJ(Obj)) {
return (double) Obj -> U.Crvs -> Length;
}
else if (IP_IS_OLST_OBJ(Obj)) {
return (double) ListObjectLength(Obj);
}
else {
WndwInputWindowPutStr("Sizeof: cannot compute object size.");
return 0.0;
}
}
/*****************************************************************************
* DESCRIPTION: M
* Gets the size of a surface mesh. M
* *
* PARAMETERS: M
* SrfObj: Surface toquery its mesh size. M
* RDir: Direction to query size. M
* *
* RETURN VALUE: M
* double: Size of mesh of SrfObj in direction RDir. M
* *
* KEYWORDS: M
* GetMeshSize M
*****************************************************************************/
double GetMeshSize(IPObjectStruct *SrfObj, RealType *RDir)
{
int Dir = REAL_PTR_TO_INT(RDir);
if (IP_IS_SRF_OBJ(SrfObj)) {
return (double) (Dir ? SrfObj -> U.Srfs -> ULength
: SrfObj -> U.Srfs -> VLength);
}
else {
WndwInputWindowPutStr("MeshSize: cannot compute non surface object size.");
return 0.0;
}
}
/*****************************************************************************
* DESCRIPTION: M
* Creates an empty list. M
* *
* PARAMETERS: M
* None *
* *
* RETURN VALUE: M
* IPObjectStruct *: A list object with emtpy list. M
* *
* KEYWORDS: M
* GetNilList M
*****************************************************************************/
IPObjectStruct *GetNilList(void)
{
IPObjectStruct
*PObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
ListObjectInsert(PObj, 0, NULL);
return PObj;
}
/*****************************************************************************
* DESCRIPTION: M
* Gets the nth object in a list. M
* *
* PARAMETERS: M
* ListObj: List object to query its n'th element. M
* Rn: The n'th element of ListObj is needed. M
* *
* RETURN VALUE: M
* IPObjectStruct *: The n'th element of ListObj M
* *
* KEYWORDS: M
* GetNthList M
*****************************************************************************/
IPObjectStruct *GetNthList(IPObjectStruct *ListObj, RealType *Rn)
{
int n = REAL_PTR_TO_INT(Rn);
IPObjectStruct *PObj;
if (!IP_IS_OLST_OBJ(ListObj)) {
WndwInputWindowPutStr("None list object ignored.");
return NULL;
}
if (n < 1 || n > ListObjectLength(ListObj)) {
WndwInputWindowPutStr("Out of range of list.");
return NULL;
}
PObj = CopyObject(NULL, ListObjectGet(ListObj, n - 1), FALSE);
return PObj;
}
/*****************************************************************************
* DESCRIPTION: M
* Appends two lists. M
* *
* PARAMETERS: M
* ListObj1, ListObj2: The two list objects to append. M
* *
* RETURN VALUE: M
* IPObjectStruct *: A combined list. M
* *
* KEYWORDS: M
* AppendLists M
*****************************************************************************/
IPObjectStruct *AppendLists(IPObjectStruct *ListObj1, IPObjectStruct *ListObj2)
{
int i, j;
IPObjectStruct *PObj, *PObjTmp;
if (!IP_IS_OLST_OBJ(ListObj1) && !IP_IS_OLST_OBJ(ListObj2)) {
WndwInputWindowPutStr("None list object ignored.");
return NULL;
}
PObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
for (i = 0; (PObjTmp = ListObjectGet(ListObj1, i)) != NULL; i++) {
ListObjectInsert(PObj, i, PObjTmp);
PObjTmp -> Count++;
}
for (j = 0; (PObjTmp = ListObjectGet(ListObj2, j)) != NULL; i++, j++) {
ListObjectInsert(PObj, i, PObjTmp);
PObjTmp -> Count++;
}
ListObjectInsert(PObj, i, NULL);
return PObj;
}
/*****************************************************************************
* DESCRIPTION: M
* Reverses a list. M
* *
* PARAMETERS: M
* ListObj: List object to reverses its entries. M
* *
* RETURN VALUE: M
* IPObjectStruct *: Reversed list object. M
* *
* KEYWORDS: M
* ReverseListObj M
*****************************************************************************/
IPObjectStruct *ReverseListObj(IPObjectStruct *ListObj)
{
int i, j;
IPObjectStruct *PObj, *PObjTmp;
if (!IP_IS_OLST_OBJ(ListObj)) {
WndwInputWindowPutStr("None list object ignored.");
return NULL;
}
PObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
for (i = ListObjectLength(ListObj) - 1, j = 0; i >= 0; i--) {
PObjTmp = ListObjectGet(ListObj, i);
ListObjectInsert(PObj, j++, PObjTmp);
PObjTmp -> Count++;
}
ListObjectInsert(PObj, j, NULL);
return PObj;
}
/*****************************************************************************
* DESCRIPTION: M
* Snoc (Cons to the end of the list, in place) the object to the list in M
* the second argument. M
* *
* PARAMETERS: M
* PObj: To snoc to ListObj. M
* ListObj: Where PObj is going to be added to, in place. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* SnocList M
*****************************************************************************/
void SnocList(IPObjectStruct *PObj, IPObjectStruct *ListObj)
{
int i;
IPObjectStruct *PObjTmp;
if (!IP_IS_OLST_OBJ(ListObj)) {
WndwInputWindowPutStr("None list object ignored.");
return;
}
i = ListObjectLength(ListObj);
ListObjectInsert(ListObj, i, PObjTmp = CopyObject(NULL, PObj, FALSE));
PObjTmp -> Count = 1;
ListObjectInsert(ListObj, i + 1, NULL);
}
/*****************************************************************************
* DESCRIPTION: M
* Gets an object by its name - scans the object linear list. M
* The termination is also on 1000 objects (simple debugging aid in case M
* the Object list became circular), and a fatal error is produced. M
* *
* PARAMETERS: M
* ObjName: Name of object to search for. M
* *
* RETURN VALUE: M
* IPObjectStruct *: Object if found, NULL otherwise. M
* *
* KEYWORDS: M
* GetObject M
*****************************************************************************/
IPObjectStruct *GetObject(char *ObjName)
{
int i = 0;
IPObjectStruct
*PObj = GlblObjList;
while (PObj) {
if (strcmp(PObj -> Name, ObjName) == 0) {
return PObj;
}
PObj = PObj -> Pnext;
if (i++ >= 1000)
IritFatalError("GetObject: Global Object list too big (>1000)");
}
return NULL;
}
/*****************************************************************************
* DESCRIPTION: M
* Extract a single entity out af an obj holding a set of entities at Index. M
* For VECTOR, POINT, CTLPT, PLANE, MAT a single numeric data is returned. M
* For a POLYGON a single vertex is returned (as VECTOR). M
* For CURVE, and SURFACE a single control point is returned. M
* *
* PARAMETERS: M
* PObj: To query for one of its coordinates. M
* RIndex: Index of coordinate. M
* *
* RETURN VALUE: M
* IPObjectStruct *: An object holding the Index coordinate of PObj. M
* *
* KEYWORDS: M
* GetObjectCoord M
*****************************************************************************/
IPObjectStruct *GetObjectCoord(IPObjectStruct *PObj, RealType *RIndex)
{
int Index = REAL_PTR_TO_INT(RIndex);
IPObjectStruct
*CoordPObj = NULL;
CagdCtlPtStruct CtlPt;
switch (PObj -> ObjType) {
case IP_OBJ_POLY:
if (PObj -> U.Pl == NULL)
break;
if (PObj -> U.Pl -> Pnext) {
IPPolygonStruct *P;
/* Extract a single poly from the poly list. */
for (P = PObj -> U.Pl;
P != NULL && Index > 0;
P = P -> Pnext, Index--);
if (P != NULL) {
IPPolygonStruct
*PTmp = IPAllocPolygon(1, P -> Tags,
CopyVertexList(P -> PVertex), NULL);
CoordPObj = GenPolyObject("", PTmp, NULL);
PLANE_COPY(PTmp -> Plane, P -> Plane);
IP_RST_BBOX_POLY(PTmp);
CoordPObj -> Attrs = AttrCopyAttributes(PObj -> Attrs);
if (IP_IS_POLYGON_OBJ(PObj))
IP_SET_POLYGON_OBJ(CoordPObj);
else if (IP_IS_POLYLINE_OBJ(PObj))
IP_SET_POLYLINE_OBJ(CoordPObj);
else if (IP_IS_POINTLIST_OBJ(PObj))
IP_SET_POINTLIST_OBJ(CoordPObj);
}
}
else {
IPVertexStruct *V;
/* Extract a vertex from the poly. */
for (V = PObj -> U.Pl -> PVertex;
V != NULL && Index > 0;
V = V -> Pnext, Index--);
if (V != NULL)
CoordPObj = GenVECObject(&V -> Coord[0], &V -> Coord[1],
&V -> Coord[2]);
}
break;
case IP_OBJ_POINT:
if (Index >= 0 && Index < 3)
CoordPObj = GenNUMValObject(PObj -> U.Pt[Index]);
break;
case IP_OBJ_VECTOR:
if (Index >= 0 && Index < 3)
CoordPObj = GenNUMValObject(PObj -> U.Pt[Index]);
break;
case IP_OBJ_PLANE:
if (Index >= 0 && Index < 4)
CoordPObj = GenNUMValObject(PObj -> U.Pt[Index]);
break;
case IP_OBJ_CTLPT:
if (!CAGD_IS_RATIONAL_PT(PObj -> U.CtlPt.PtType) && Index == 0)
break;
if (Index >= 0 &&
Index <= CAGD_NUM_OF_PT_COORD(PObj -> U.CtlPt.PtType))
CoordPObj = GenNUMValObject(PObj -> U.CtlPt.Coords[Index]);
break;
case IP_OBJ_MATRIX:
if (Index >= 0 && Index < 16)
CoordPObj =
GenNUMValObject((*PObj -> U.Mat)[Index / 4][Index % 4]);
break;
case IP_OBJ_LIST_OBJ:
CoordPObj = GetNthList(PObj, RIndex);
break;
case IP_OBJ_CURVE:
if (PObj -> U.Crvs == NULL)
break;
if (PObj -> U.Crvs -> Pnext != NULL) {
CagdCrvStruct *Crv;
/* Extract a single curve from the curve list. */
for (Crv = PObj -> U.Crvs;
Crv != NULL && Index > 0;
Crv = Crv -> Pnext, Index--);
if (Crv != NULL)
CoordPObj = GenCRVObject(CagdCrvCopy(Crv));
}
else {
/* Extract a ctlpt from the curve. */
CagdEditSingleCrvPt(PObj -> U.Crvs, &CtlPt, Index, FALSE);
CoordPObj = GenCTLPTObject(PObj -> U.Crvs -> PType,
CtlPt.Coords, NULL);
}
break;
case IP_OBJ_SURFACE:
if (PObj -> U.Srfs == NULL)
break;
if (PObj -> U.Srfs -> Pnext != NULL) {
CagdSrfStruct *Srf;
/* Extract a single surface from the surface list. */
for (Srf = PObj -> U.Srfs;
Srf != NULL && Index > 0;
Srf = Srf -> Pnext, Index--);
if (Srf != NULL)
CoordPObj = GenSRFObject(CagdSrfCopy(Srf));
}
else {
/* Extract a ctlpt from the surface. */
CagdEditSingleSrfPt(PObj -> U.Srfs, &CtlPt,
Index / PObj -> U.Srfs -> ULength,
Index % PObj -> U.Srfs -> ULength,
FALSE);
CoordPObj = GenCTLPTObject(PObj -> U.Srfs -> PType,
CtlPt.Coords, NULL);
}
break;
default:
break;
}
if (CoordPObj == NULL)
WndwInputWindowPutStr("Coord: Out of range or wrong object type.");
return CoordPObj;
}